package com.taxshare.seller.util;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/***
 * 时间转换工具类
 *
 * @author
 */
public class DateUtils {

    private static Object timeZoneLock = new Object();

    private static String[][] timeZoneList;

    private static Map<String, DateFormat> dateFormatCache = new HashMap<>();

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    public static SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
    /**
     * 时间类型
     */
    public static enum TimeType {
        /**
         * 毫秒
         */
        diffMillis,
        /**
         * 秒
         */
        diffSecs,
        /**
         * 分钟
         */
        diffMins,
        /**
         * 小时
         */
        diffHours,
        /**
         * 天
         */
        diffDays;
    }

    /**
     * 构造函数
     */
    private DateUtils() {

    }

    /**
     * 描述：获取指定的Date对象
     *
     * @param yy 指定年
     * @param mm 指定月
     * @param dd 指定天
     * @return java.util.Date日期格式
     */
    public static Date getDate(int yy, int mm, int dd) {
        return new GregorianCalendar(yy, mm - 1, dd).getTime();
    }

    /**
     * 描述：日期比较
     *
     * @param rq1 源日期A
     * @param rq2 源日期B
     * @return rq1=rq2：0/rq1>rq2:-1/rq1<rq2:1
     */
    public static int getCompareDate(Date rq1, Date rq2) {
        int flag = 0;
        try {
            flag = rq1.compareTo(rq2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 描述：将日期转换为特定格式字符串 date>yyyy-MM-dd
     *
     * @param date 指定日期
     * @return String
     */
    public static String getDateToStr(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String datestr = sdf.format(date);
        return datestr;
    }

    /**
     * 描述：将日期转换为特定格式字符串 date>yyyy-MM-dd
     * @return String
     */
    public static String getDateToStr() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String datestr = sdf.format(new Date());
        return datestr;
    }
    
    public static String getDateToStr01() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String datestr = sdf.format(new Date());
        return datestr;
    }

    /**
     * 描述：将TimeZone日期转换为特定格式字符串 date>yyyy-MM-dd
     *
     * @param date     指定日期
     * @param timeZone 时区
     * @return String
     */
    public static String getDateToStr(Date date, TimeZone timeZone) {
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        formatter.setTimeZone(timeZone);
        return formatter.format(date);
    }


    /**
     * 描述：将日期转换为特定格式字符串 date>yyyy-MM-dd HH:mm:ss
     *
     * @param date 指定日期
     * @return String
     */
    public static String getDateToStrHms(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datestr = sdf.format(date);
        return datestr;
    }

    /**
     * 描述：将TimeZone日期转换为特定格式字符串 date>yyyy-MM-dd HH:mm:ss
     *
     * @param date     指定日期
     * @param timeZone 时区
     * @return String
     */
    public static String getDateToStrHms(Date date, TimeZone timeZone) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(timeZone);
        return sdf.format(date);
    }

    /**
     * 描述：将日期转换为特定格式字符串 date>yyyy-MM-dd HH:mm:ss
     * @return String
     */
    public static String getDateToStrHms() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datestr = sdf.format(new Date());
        return datestr;
    }

    /**
     * 描述：将日期转换为指定格式字符串
     *
     * @param date   指定日期
     * @param format 指定的日期格式
     * @return String
     */
    public static String getDateStrFormat(Date date, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String datestr = sdf.format(date);
        return datestr;
    }

    /**
     * 描述:将字符串格式日期转换为指定日期格式
     *
     * @param dateStr 指定日期字符串
     * @param format  指定日期格式
     * @return Date
     */
    public static Date getStrDateFormat(String dateStr, String format) {
        if ((dateStr == null) || (dateStr.length() == 0) || (format == null)
                || (format.length() == 0)) {
            return null;
        }
        DateFormat fmt = new SimpleDateFormat(format);
        Date result = null;
        try {
            result = fmt.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 描述： 将日期字符串中的阿拉伯数字格式化为汉字
     *
     * @param str 字符串字符
     * @param sf  接受的字符对象
     * @return StringBuffer
     */
    public static StringBuffer getStrToHZ(String str, StringBuffer sf) {
        char sign = 0;
        for (int i = 0, len = str.length(); i < len; i++) {
            sign = str.charAt(i);
            switch (sign) {
                case '0':
                    sign = '零';
                    break;
                case '1':
                    sign = '一';
                    break;
                case '2':
                    sign = '二';
                    break;
                case '3':
                    sign = '三';
                    break;
                case '4':
                    sign = '四';
                    break;
                case '5':
                    sign = '五';
                    break;
                case '6':
                    sign = '六';
                    break;
                case '7':
                    sign = '七';
                    break;
                case '8':
                    sign = '八';
                    break;
                case '9':
                    sign = '九';
                    break;
                default:
                    break;
            }
            sf.append(sign);
        }
        return sf;
    }

    /**
     * 描述: 计算分钟差（单位：timeType）
     *
     * @param data1    指定日期1
     * @param data2    指定日期2
     * @param timeType 时间差类型枚举 TimeType（毫秒、秒、分钟、小时、天）
     * @return long
     */
    public static long getTimeDiffMins(String data1, String data2, TimeType timeType) {
        Calendar c1 = new GregorianCalendar(Integer.parseInt(data1.substring(0,
                4)), Integer.parseInt(data1.substring(5, 7)), Integer
                .parseInt(data1.substring(8, 10)), Integer.parseInt(data1
                .substring(11, 13)), Integer.parseInt(data1.substring(14, 16)));
        Calendar c2 = new GregorianCalendar(Integer.parseInt(data2.substring(0,
                4)), Integer.parseInt(data2.substring(5, 7)), Integer
                .parseInt(data2.substring(8, 10)), Integer.parseInt(data2
                .substring(11, 13)), Integer.parseInt(data2.substring(14, 16)));

        long diffMillis = 0L;
        if (c1.after(c2))
            diffMillis = c1.getTimeInMillis() - c2.getTimeInMillis();
        else {
            diffMillis = c2.getTimeInMillis() - c1.getTimeInMillis();
        }
        if (timeType == TimeType.diffMillis)
            return diffMillis;
        if (timeType == TimeType.diffSecs)
            return diffMillis / 1000L;
        if (timeType == TimeType.diffMins)
            return diffMillis / 60000L;
        if (timeType == TimeType.diffHours) {
            return diffMillis / 3600000L;
        }
        return diffMillis / 86400000L;
    }

    /**
     * 描述：将无分隔符日期转换为普通分隔符日期 1970-01-01
     *
     * @param date 指定日期
     * @return String
     */
    public static String getDateStrToIndex(String date) {
        String indexDate = "19700101";
        if ((date != null) && (date.trim().length() >= 10)) {
            int i = date.indexOf(" ");
            if (i != -1)
                indexDate = date.substring(0, i).replaceAll("-", "").replace(
                        "/", "");
            else {
                indexDate = date.replaceAll("-", "").replace("/", "");
            }
        }
        return indexDate;
    }

    /**
     * 描述：将日期分隔符去掉 支持 "/","-"字符 19700101>1970-01-01
     *
     * @param indexDate 数字日期格式
     * @return String
     */
    public static String getIndexToDateStr(String indexDate) {
        StringBuilder sb = new StringBuilder("1970-01-01");
        if ((indexDate != null) && (indexDate.trim().length() == 8)) {
            sb = new StringBuilder(indexDate);
            sb.insert(4, '-');
            sb.insert(7, '-');
        }
        return sb.toString();
    }

    /**
     * 描述：将日期对象按默认时区转换成"yyyy-MM-dd HH:mm:ss"格式的字符串
     *
     * @param date 日期格式
     * @return String
     */
    public static String getTimeZoneToString(Date date) {
        return getTimeZoneToString(date, TimeZone.getDefault());
    }

    /**
     * 描述：将日期对象按指定时区转换成"yyyy-MM-dd HH:mm:ss"格式的字符串
     *
     * @param date     指定日期
     * @param timeZone 时区
     * @return String
     */
    public static String getTimeZoneToString(Date date,
                                             TimeZone timeZone) {
        String key = timeZone.getID();
        DateFormat formatter = (DateFormat) dateFormatCache.get(key);
        if (formatter == null) {
            formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            formatter.setTimeZone(timeZone);
            dateFormatCache.put(key, formatter);
        }
        synchronized (formatter) {
            return formatter.format(date);
        }
    }

    /**
     * 描述：获取给定秒的日期
     *
     * @param time int秒数
     * @return Date 日期格式
     */
    public static Date getSecondsToTime(int time) {
        return new Date(time * 1000L);
    }

    /**
     * 描述： 获取当前时间的秒
     *
     * @return int
     */
    public static int getTimeToSeconds() {
        return (int) (System.currentTimeMillis() / 1000L);
    }

    /**
     * 描述：获取指定日期的秒
     *
     * @param date 指定日期
     * @return int
     */
    public static int getTimeSecs(Date date) {
        return (int) (date.getTime() / 1000L);
    }


    /**
     * 描述：获取指定2个日期时间的秒差
     *
     * @param sd 开始日期
     * @param ed 结束日期
     * @return int
     */
    public static int getSecondsDiffSecs(Date sd, Date ed) {
        return (int) ((sd.getTime() - ed.getTime()) / 1000L);
    }

    /**
     * 获得任意天的是星期几
     *
     * @param y 指定 年
     * @param m 指定 月
     * @param d 指定 天
     * @return int
     */
    public static int getWeek(int y, int m, int d) {
        if (m < 3) {
            m += 12;
            y--;
        }
        int w = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + (y >> 2) - y / 100 + y / 400) % 7;
        return w;
    }

    /**
     * 描述：获得日期是星期几
     *
     * @param date 指定日期
     * @return String
     */
    public static String getChineseWeek(Date date) {
        Calendar d1 = Calendar.getInstance();
        d1.setTime(date);
        String[] dayNames = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        int dayOfWeek = d1.get(7);
        return dayNames[(dayOfWeek - 1)];
    }

    /**
     * 描述 ：获取全部时区
     *
     * @return String[][] 时区集合
     */
    public static String[][] getTimeZoneList() {
        synchronized (timeZoneLock) {
            if (timeZoneList == null) {
                Date now = new Date();
                String[] timeZoneIDs = TimeZone.getAvailableIDs();
                timeZoneList = new String[timeZoneIDs.length][2];
                for (int i = 0; i < timeZoneList.length; i++) {
                    String zoneID = timeZoneIDs[i];
                    timeZoneList[i][0] = zoneID;
                    timeZoneList[i][1] = getTimeZoneName(zoneID, now, Locale
                            .getDefault());
                }
            }
        }
        return timeZoneList;
    }


    /**
     * 描述：将日期String转化成当前年龄(如1984年09月8日->24)
     *
     * @param date 指定日期字符串
     * @return int
     */
    public static int getDateToAge(String date) {
        int age = 0;
        if ("".equals(date.trim())) {
            return 0;
        }
        try {
            Date dt = getStrDateFormat(date, "yyyy-MM-dd");
            Calendar c = Calendar.getInstance();
            c.setTime(new Date());
            int y1 = c.get(Calendar.YEAR);
            int m1 = c.get(Calendar.DAY_OF_YEAR);
            c.setTime(dt);
            int y2 = c.get(Calendar.YEAR);
            int m2 = c.get(Calendar.DAY_OF_YEAR);
            age = m1 >= m2 ? (y1 - y2) : y1 - y2 - 1;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return age;
    }

    /**
     * 描述：取得指定日期增加/减少（n为负数时）n天后的日期
     *
     * @param num    指定天数
     * @param format 日期格式
     * @return String
     */
    public static String getCalcDateFormat(int num, String format) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.add(5, num);
        Date time = gc.getTime();
        return getDateStrFormat(time, format);
    }

    /**
     * 描述：获取指定日期当月总天数
     *
     * @param date 指定日期
     * @return int 天数
     */
    public static int getMonthTotalDay(Date date) {
        if (date == null) {
            return 0;
        }
        int year = Integer.parseInt(date.toString().substring(0, 4));
        int month = Integer.parseInt(date.toString().substring(5, 7));
        Calendar cal = Calendar.getInstance();
        cal.set(1, year);
        cal.set(2, month - 1);
        cal.set(5, 1);
        return cal.getActualMaximum(5);
    }

    /**
     * 描述:获取指定日期当月最后一天
     *
     * @param date 指定日期
     * @return Date日期格式
     * @throws Exception 异常
     */
    public static Date getMonthEnd(Date date)
            throws Exception {
        if (date == null) {
            return null;
        }
        int year = Integer.parseInt(date.toString().substring(0, 4));
        int month = Integer.parseInt(date.toString().substring(5, 7));
        Calendar cal = Calendar.getInstance();
        cal.set(1, year);
        cal.set(2, month - 1);
        cal.set(5, getMonthTotalDay(date));

        Date d = new Date(cal.getTime().getTime());
        return d;
    }

    /**
     * 描述： 获取指定日期的月中
     *
     * @param date 指定日期
     * @return Date日期格式
     * @throws Exceptione 异常
     */
    public static Date getMonthMid(Date date)
            throws Exception {
        if (date == null) {
            return null;
        }
        int year = Integer.parseInt(date.toString().substring(0, 4));
        int month = Integer.parseInt(date.toString().substring(5, 7));
        Calendar cal = Calendar.getInstance();
        cal.set(1, year);
        cal.set(2, month - 1);
        cal.set(5, 15);

        Date d = new Date(cal.getTime().getTime());
        return d;
    }

    /**
     * 描述：获取指定日期的下个月月出第一天
     *
     * @param date 指定日期
     * @return Date日期格式
     * @throws Exceptione 异常
     */
    public static Date getNextMonthFirst(Date date)
            throws Exception {
        if (date == null) {
            return null;
        }
        int year = Integer.parseInt(date.toString().substring(0, 4));
        int month = Integer.parseInt(date.toString().substring(5, 7));

        if (month == 12) {
            year++;
            month = 1;
        } else {
            month++;
        }
        Calendar cal = Calendar.getInstance();
        cal.set(1, year);
        cal.set(2, month - 1);
        cal.set(5, 1);

        Date d = new Date(cal.getTime().getTime());
        return d;
    }

    /**
     * 描述：获取指定日期的上个月月末最后一天
     *
     * @param date 指定日期
     * @return Date Date日期格式
     */
    public static Date getPreviousMonthEnd(Date date)
            throws Exception {
        if (date == null) {
            return null;
        }
        int year = Integer.parseInt(date.toString().substring(0, 4));
        int month = Integer.parseInt(date.toString().substring(5, 7));

        if (month == 1) {
            year--;
            month = 12;
        } else {
            month--;
        }
        Calendar cal = Calendar.getInstance();
        cal.set(1, year);
        cal.set(2, month - 1);
        cal.set(5, 1);
        Date d = new Date(cal.getTime().getTime());
        cal.set(5, getMonthTotalDay(d));
        d = new Date(cal.getTime().getTime());
        return d;
    }

    /**
     * 描述：获取指定日期的前一天日期
     *
     * @param date 指定日期
     * @return Date日期格式
     *
     */
    public static Date getPreviousDay(Date date)
            throws Exception {
        if (date == null) {
            return null;
        }
        int year = Integer.parseInt(date.toString().substring(0, 4));
        int month = Integer.parseInt(date.toString().substring(5, 7));
        int day = Integer.parseInt(date.toString().substring(8, 10));
        if (day == 1) {
            if (month == 1) {
                year--;
                month = 12;
                day = 31;
            } else {
                month--;
                Calendar c = Calendar.getInstance();
                c.set(1, year);
                c.set(2, month - 1);
                c.set(5, 1);
                Date d = new Date(c.getTime().getTime());
                day = getMonthTotalDay(d);
            }
        } else
            day--;

        Calendar c = Calendar.getInstance();
        c.set(1, year);
        c.set(2, month - 1);
        c.set(5, day);
        Date d = new Date(c.getTime().getTime());

        return d;
    }

    /**
     * 描述：获取指定日期的下一天日期
     *
     * @param date 指定日期
     * @return Date日期格式
     *
     */
    public static Date getNextDay(Date date) throws Exception {
        if (date == null) {
            return null;
        }
        int year = Integer.parseInt(date.toString().substring(0, 4));
        int month = Integer.parseInt(date.toString().substring(5, 7));
        int day = Integer.parseInt(date.toString().substring(8, 10));

        if (day == getMonthTotalDay(date)) {
            if (month == 12) {
                year++;
                month = 1;
            } else {
                month++;
            }
            day = 1;
        } else {
            day++;
        }
        Calendar c = Calendar.getInstance();
        c.set(1, year);
        c.set(2, month - 1);
        c.set(5, day);
        Date d = new Date(c.getTime().getTime());

        return d;
    }

    /**
     * 描述：获得日期的下一个星期一的日期
     *
     * @param date 指定日期
     * @return Date日期格式
     */
    public static Date getNextMonday(Date date) {
        Calendar d1 = Calendar.getInstance();
        d1.setTime(date);
        Date result = date;
        do {
            d1 = (Calendar) d1.clone();
            d1.add(5, 1);
        } while (d1.get(7) != 2);

        result = new Date(d1.getTime().getTime());
        return result;
    }

    /**
     * 描述：获取指定日期加上指定天数日期
     *
     * @param date 指定日期
     * @param days 指定天数
     * @return String 日期
     */
    public static String getAddDaysDate(Date date, int days) {
        long das = date.getTime() / 86400000L + days + 1L;
        return getDateToStr(new Date(das * 86400000L));
    }

    /**
     * 描述：获取指定日期加上指定天数
     *
     * @param date 指定日期
     * @param days 指定天数
     * @return String 日期
     */
    public static String getAddDaysDate(String date, int days) {
        Date d = getStrDateFormat(date, "yyyy-MM-dd");
        long das = d.getTime() / 86400000L + days + 1L;
        return getDateToStr(new Date(das * 86400000L));
    }

    /**
     * 描述：获取日期差天数
     *
     * @param sd 开始日期
     * @param ed 结束日期
     * @return long 差距值
     */
    public static long getDateDiffIsDays(Date sd, Date ed) {
        return (ed.getTime() - sd.getTime()) / 86400000L;
    }

    /**
     * 描述：获取日期差月数
     *
     * @param mind 开始日期
     * @param maxd 结束日期
     * @return int 差距值
     */
    public static int getDateDiffIsMonths(Date mind, Date maxd) {
        Calendar d1 = Calendar.getInstance();
        Calendar d2 = Calendar.getInstance();
        d1.setTime(maxd);
        d2.setTime(mind);
        int year = d1.get(Calendar.YEAR);
        int month = d1.get(Calendar.MONTH);
        int year1 = d2.get(Calendar.YEAR);
        int month1 = d2.get(Calendar.MONTH);
        int xc = (year - year1) * 12 + (month - month1);
        if (xc < 0) {
            xc = 0;
        }
        return xc;
    }

    /**
     * 描述 ： 计算2个日期之间的工作日(去除周六、日)天数
     *
     * @param sd 开始日期
     * @param ed 结束日期
     * @return int
     */
    public static int getWorkingDays(Date sd, Date ed) {
        Calendar d1 = Calendar.getInstance();
        Calendar d2 = Calendar.getInstance();
        d1.setTime(sd);
        d2.setTime(ed);
        int result = -1;
        if (d1.after(d2)) {
            Calendar swap = d1;
            d1 = d2;
            d2 = swap;
        }
        int chargeStartDate = 0;
        int chargeEndDate = 0;
        int stmp = 7 - d1.get(7);
        int etmp = 7 - d2.get(7);

        if ((stmp != 0) && (stmp != 6)) {
            chargeStartDate = stmp;
        }
        if ((etmp != 0) && (etmp != 6)) {
            chargeEndDate = etmp - 1;
        }
        result = ((int) getDateDiffIsDays(getNextMonday(sd), getNextMonday(ed)) + 1)
                / 7 * 5 + chargeStartDate - chargeEndDate;
        return result;
    }

    /**
     * 描述：计算2个日期之间的休息日(周六、日)天数
     *
     * @param sd 开始日期
     * @param ed 结束日期
     * @return int
     */
    public static int getHolidays(Date sd, Date ed) {
        return (int) getDateDiffIsDays(sd, ed) + 1 - getWorkingDays(sd, ed);
    }

    /**
     * 描述 ： 将util时间转换为sql时间
     *
     * @param date java.util.Date 日期
     * @return java.sql.Date
     */
    public static java.sql.Date getConvertUtilDateToSqlDate(Date date) {
        java.sql.Date cd = null;
        try {
            cd = new java.sql.Date(date.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cd;
    }

    /**
     * 描述：获取指定日期的年
     *
     * @param date 指定日期
     * @return int
     */
    public static int getYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    /**
     * 描述：获取指定字符串日期的年
     *
     * @param date 指定日期
     * @return int
     */
    public static int getYear(String date) {
        String syear = date.substring(0, 4);
        return Integer.parseInt(syear);
    }

    /**
     * 描述：取得该日期的月
     *
     * @param date 指定日期
     * @return int
     */
    public static int getMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 描述： 取得该字符串的月
     *
     * @param date     日期字符串
     * @param separate 分隔符
     * @return int
     */
    public static int getMonth(String date, String separate) {
        StringBuffer smon = new StringBuffer();
        String smon1 = date.substring(5, 6);
        String smon2 = date.substring(6, 7);
        if (smon2.equals(separate)) {
            smon.append(smon1);
        } else {
            smon.append(smon1);
            smon.append(smon2);
        }
        return Integer.parseInt(smon.toString());
    }

    /**
     * 描述：取得该日期的天
     *
     * @param date 指定日期
     * @return int
     */
    public static int getDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 描述：获得直指定年-月最大天数
     *
     * @param year  指定年
     * @param month 指定月
     * @return int
     */
    public static int getYearMonMax(int year, int month) {
        if ((month == 1) || (month == 3) || (month == 5) || (month == 7)
                || (month == 8) || (month == 10) || (month == 12)) {
            return 31;
        }
        if (month != 2) {
            return 30;
        }
        if (isLeap(year)) {
            return 29;
        }
        return 28;
    }

    /**
     * 描述:如果是闰年，返回true 否则返回false
     *
     * @param year 指定年
     * @return boolean
     */
    public static boolean isLeap(int year) {
        if (year % 4 != 0) {
            return false;
        }

        if (year % 100 != 0) {
            return true;
        }
        return year % 400 == 0;
    }

    /**
     * 描述：判断字符串是否是日期时间 例"1981-12-12 12:12:12"
     *
     * @param str 日期源字符串
     * @return boolean
     */
    public static boolean isDateYMDHMS(String str) {
        if (str == null) {
            return true;
        }
        return str
                .matches("^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29)) ([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$");
    }

    /**
     * 描述：判断字符串是否是日期 例如"1981-12-12"
     *
     * @param str 日期源字符串
     * @return boolean
     */
    public static boolean isDateYMD(String str) {
        if (str == null) {
            return true;
        }
        return str
                .matches("^((((1[6-9]|[2-9]\\d)\\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\\d|3[01]))|(((1[6-9]|[2-9]\\d)\\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\\d|30))|(((1[6-9]|[2-9]\\d)\\d{2})-0?2-(0?[1-9]|1\\d|2[0-8]))|(((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29))$");
    }

    /**
     * 描述：判断字符串是否是时间 例"12:12:12"
     *
     * @param str 日期源字符串
     * @return boolean
     */
    public static boolean isDateHMS(String str) {
        if (str == null) {
            return true;
        }
        return str.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$");
    }

    private static String getTimeZoneName(String zoneID, Date now,
                                          Locale locale) {
        TimeZone zone = TimeZone.getTimeZone(zoneID);
        StringBuffer buf = new StringBuffer();
        int offset = zone.getRawOffset();
        if ((zone.inDaylightTime(now)) && (zone.useDaylightTime())) {
            offset = (int) (offset + 3600000L);
        }
        if (offset < 0)
            buf.append("(GMT-");
        else {
            buf.append("(GMT+");
        }
        offset = Math.abs(offset);
        int hours = offset / 3600000;
        int minutes = offset % 3600000 / 60000;
        if (hours < 10)
            buf.append("0").append(hours).append(":");
        else {
            buf.append(hours).append(":");
        }
        if (minutes < 10)
            buf.append("0").append(minutes);
        else {
            buf.append(minutes);
        }
        buf.append(") ").append(zoneID).append(" ");
        buf.append(zone.getDisplayName(true, 0, locale));
        return buf.toString();
    }

    /**
     * 获取当前月的第一天
     * @return
     */
    public static String getCurrentMonthFirst() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
        String first = sdf.format(c.getTime());
        return first;
    }
    /**
     * @Title: getDaysOfMonth
     * @Description: (获取某个月的天数)
     * @param @param date
     * @param @return    参数
     * @return int    返回类型
     * @throws
  */
	 public static int getDaysOfMonth(Date date) {
	     Calendar calendar = Calendar.getInstance();
	     calendar.setTime(date);
	     return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	 }
	 
	 /**
	
	  * 获取指定日期下个月的第一天
	 * @param dateStr
	 * @param format
	 * @return
	 */
	 public static String getFirstDayOfNextMonth(String dateStr,String format){
	 SimpleDateFormat sdf = new SimpleDateFormat(format);
	 try {
		 Date date = sdf.parse(dateStr);
		 Calendar calendar = Calendar.getInstance();
		 calendar.setTime(date);
		 calendar.set(Calendar.DAY_OF_MONTH,1);
		 calendar.add(Calendar.MONTH, 1);
		 return sdf.format(calendar.getTime());
	 } catch (ParseException e) {
		 e.printStackTrace();
	 }
	 return null;
	 }

    /**

      * 获取指定日期下下个月的第一天
     * @param dateStr
     * @param format
     * @return
     */
    public static String getFirstDayOfNextMonth01(String dateStr,String format){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            Date date = sdf.parse(dateStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH,1);
            calendar.add(Calendar.MONTH, 2);
            return sdf.format(calendar.getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
	 
	 /**
	     * @Title: getNextTime
	     * @Description: (时间戳生成id)
	     * @param @return    参数
	     * @return String    返回类型
	     * @throws
	  */
	 public static String getNextTime() {
		 AtomicLong atomicTimeMills = new AtomicLong(0);
		 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
		    while (true) {
		        long currentMill = atomicTimeMills.get();
		        Long currentTimeMillis = Long.parseLong(LocalDateTime.now().format(formatter) + System.nanoTime()%100);
		        if (currentTimeMillis > currentMill && atomicTimeMills.compareAndSet(currentMill, currentTimeMillis)) {
		            return currentTimeMillis.toString();
		        }
		    }
		}

	 public static boolean isValidExcelDate(double value) {
		    return value > -4.940656458412465E-324D;
		  }
	 public static boolean isInternalDateFormat(int format) {
		    switch (format) {
		    case 14: 
		    case 15: 
		    case 16: 
		    case 17: 
		    case 18: 
		    case 19: 
		    case 20: 
		    case 21: 
		    case 22: 
		    case 45: 
		    case 46: 
		    case 47: 
		      return true;
		    }
		    
		    
		    return false;
		  }
	 public static boolean isADateFormat(int formatIndex, String formatString) {
		    if (isInternalDateFormat(formatIndex)) {
		      return true;
		    }
		    if ((formatString == null) || (formatString.length() == 0)) {
		      return false;
		    }
		    String fs = formatString;
		    fs = fs.replaceAll("\\\\-", "-");
		    fs = fs.replaceAll("\\\\,", ",");
		    fs = fs.replaceAll("\\\\.", ".");
		    fs = fs.replaceAll("\\\\ ", " ");
		    fs = fs.replaceAll(";@", "");
		    fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");
		    fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");
		    fs = fs.replaceAll("[\"|']", "").replaceAll("[年|月|日|时|分|秒|毫秒|微秒]", "");
		    return fs.matches("^[yYmMdDhHsS\\-/,. :]+[ampAMP/]*$");
		  }
	 public static boolean isCellDateFormatted(Cell cell) {
		    if (cell == null)
		      return false;
		    boolean bDate = false;
		    double d = cell.getNumericCellValue();
		    if (isValidExcelDate(d)) {
		      CellStyle style = cell.getCellStyle();
		      if (style == null)
		        return false;
		      int i = style.getDataFormat();
		      String f = style.getDataFormatString();
		      bDate = isADateFormat(i, f);
		    }
		    return bDate;
		  }

    public static String fomatterOP5(String strDate) {
        String pat1 = "yyyy-MM-dd HH:mm:ss";
        // 准备第二个模板，将提取后的日期数字变为指定的格式
        String pat2 = "yyyy-MM-dd";
        String res = "";
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1);        // 实例化模板对象
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2);        // 实例化模板对象
        Date d = null;
        try {
            d = sdf1.parse(strDate);   // 将给定的字符串中的日期提取出来
        } catch (Exception e) {            // 如果提供的字符串格式有错误，则进行异常处理
            e.printStackTrace();       // 打印异常信息
        }
        res = sdf2.format(d);    // 将日期变为新的格式
        return res;
    }

    public static String getDateToStr02() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String datestr = sdf.format(new Date());
        return datestr;
    }

    public static String fomatterOP6(String strDate) {
        String pat1 = "yyyy-MM-dd";
        // 准备第二个模板，将提取后的日期数字变为指定的格式
        String pat2 = "yyyy-MM-dd HH:mm:ss";
        String res = "";
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1);        // 实例化模板对象
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2);        // 实例化模板对象
        Date d = null;
        try {
            d = sdf1.parse(strDate);   // 将给定的字符串中的日期提取出来
        } catch (Exception e) {            // 如果提供的字符串格式有错误，则进行异常处理
            e.printStackTrace();       // 打印异常信息
        }
        res = sdf2.format(d);    // 将日期变为新的格式
        return res;
    }

    public static String fomatterOP7(String strDate) {
        String pat2 = "yyyyMMdd";
        // 准备第二个模板，将提取后的日期数字变为指定的格式
        String pat1 = "yyyy-MM-dd";
        String res = "";
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1);        // 实例化模板对象
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2);        // 实例化模板对象
        Date d = null;
        try {
            d = sdf1.parse(strDate);   // 将给定的字符串中的日期提取出来
        } catch (Exception e) {            // 如果提供的字符串格式有错误，则进行异常处理
            e.printStackTrace();       // 打印异常信息
        }
        res = sdf2.format(d);    // 将日期变为新的格式
        return res;
    }

    public static String fomatterOP8(String strDate) {
        String pat1 = "yyyyMMdd";
        // 准备第二个模板，将提取后的日期数字变为指定的格式
        String pat2 = "yyyy-MM-dd";
        String res = "";
        SimpleDateFormat sdf1 = new SimpleDateFormat(pat1);        // 实例化模板对象
        SimpleDateFormat sdf2 = new SimpleDateFormat(pat2);        // 实例化模板对象
        Date d = null;
        try {
            d = sdf1.parse(strDate);   // 将给定的字符串中的日期提取出来
        } catch (Exception e) {            // 如果提供的字符串格式有错误，则进行异常处理
            e.printStackTrace();       // 打印异常信息
        }
        res = sdf2.format(d);    // 将日期变为新的格式
        return res;
    }

    public static String getDatetoDay(String dateStr) {
        try {
            DateFormat formatM = new SimpleDateFormat("yyyyMMddHHmmss");
            SimpleDateFormat shortSdf = new SimpleDateFormat("yyyy-MM-dd");
            return shortSdf.format(formatM.parse(dateStr)) ;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 从内容中找到 YYYY-MM-dd
     * @param content
     * @return
     */
    public static String getDate(String content){
        Pattern p = Pattern.compile("(\\d{4})-(\\d{1,2})-(\\d{1,2})");
        Matcher matcher = p.matcher(content);
        while (matcher.find()) {
            return matcher.group(0);
        }
        return "";
    }


}
